/**************************************************************************//**
 * @file     hal_stm32f1xx_uart_api.h
 * @brief    stm32f1xx UART模块对外提供的公共接口
 * @version  V0.0.1
 * @date     2020-02-01
 ******************************************************************************/
/*
 * Copyright (c) 2004, 2005 by xiao xiang. All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * is freely granted, provided that this notice is preserved.
 */
#ifndef _HAL_STM32F1XX_UART_API_H_
#define _HAL_STM32F1XX_UART_API_H_

#include "common.h"
#include "hal_stm32f1xx_reg_base_api.h"

/*
 * 数据发送基本步骤：
 * 1、初始化：设置UE激活USART，编程M定义字长，编程停止位的位数，配置DMA，设置波特率
 * 2、设置USART_CR1中的TE位，发送一个空闲帧作为第一次数据发送。（如不做此操作，会丢失第1帧）
 * 2、先向数据寄存器DR写入要发送的第一个数据（这将清除TXE位），待TXE置1（说明数据已经转移到移位寄存器开始发送），
 *    继续向DR写入要发送的数据，直到全部写入完成。
 * 3、待最后一个数据写完，TXE置1，这时等待TC位置1，说明最后一帧传输完成
 */

/**
  * @brief 状态寄存器(USART_SR)
  * @note 地址偏移： 0x00   复位值： 0x00C0
  */
typedef union {
    struct {
        __IM uint32_t PE   :1;   /*!< 校验错误 (Parity error) 0=无错误 1=有奇偶校验错误 */
        __IM uint32_t FE   :1;   /*!< 帧错误 (Framing error) 0=无错误 1=有帧错误 */
        __IM uint32_t NE   :1;   /*!< 噪声错误标志 (Noise error flag) 0=无错误 1=有噪声错误 */
        __IM uint32_t ORE  :1;   /*!< ORE：过载错误 (Overrun error) 0=无错误 1=有过载错误 */
        __IM uint32_t IDLE :1;   /*!< 监测到总线空闲 (IDLE line detected) 0=没有检测到总线空闲  1=总线空闲 */
        __IM uint32_t RXNE :1;   /*!< 读数据寄存器非空 (Read data register not empty) 0=未收到数据 1=收到数据 读DR寄存器清除 */
        __IM uint32_t TC   :1;   /*!< 发送完成 (Transmission complete) 0=发送未完成 1=发送完成(前提是TXE=1，否则保持0) */
        __IM uint32_t TXE  :1;   /*!< 发送数据寄存器空 (Transmit data register empty) 0=数据还没有被转移到移位寄存器 1=数据已转移
                                      当TDR寄存器中的数据被硬件转移到移位寄存器时，该位被硬件置位，对USART_DR的写可以将该位清零。 */
        __IM uint32_t LBD  :1;   /*!< LIN断开检测标志 (LIN break detection flag)  0=没有检测到LIN断开 1=检测到LIN断开 */
        __IM uint32_t CTS  :1;   /*!< CTS 标志 (CTS flag) 0=nCTS状态线上没有变化 1=nCTS状态线上发生变化 */
             uint32_t RSV  :22;
    };
    __IM uint32_t reg;
} UN_USART_SR;

/** 
  * @brief 数据寄存器(USART_DR)
  * @note 地址偏移： 0x04   复位值： 不确定
  */
typedef union {
    struct {
        __IOM uint32_t DR  :9;    /*!< 保存发送或接收的数据，实际是两个寄存器，写的时候是TDR，都的时候是RDR。
                                       使能校验功能后，最高bit位作为校验位，由硬件设置 */
              uint32_t RSV :23;
    };
    __IOM uint32_t reg;
} UN_USART_DR;

/** 
  * @brief 波特比率寄存器(USART_BRR)
  * @note 地址偏移： 0x08   复位值： 0x0000
  * @note 如果TE或RE被分别禁止，波特计数器停止计数
  */
typedef union {
    struct {
        __IOM uint32_t DIV_Fraction :4;   /*!< USARTDIV的小数部分 */
        __IOM uint32_t DIV_Mantissa :12;  /*!< USARTDIV的整数部分 */
              uint32_t RSV          :16;
    };
    __IOM uint32_t reg;
} UN_USART_BRR;

/** 
  * @brief  控制寄存器 1(USART_CR1)
  * @note   地址偏移： 0x0C   复位值： 0x0000
  */
typedef union {
    struct {
        __IOM uint32_t SBK     :1;  /*!< 发送断开帧 (Send break) */
        __IOM uint32_t RWU     :1;  /*!< 接收唤醒 (Receiver wakeup),用于地址唤醒 */
        __IOM uint32_t RE      :1;  /*!< 接收使能 (Receiver enable) 0=禁止接收 1=允许接收 */
        __IOM uint32_t TE      :1;  /*!< 发送使能 (Transmitter enable) 0=禁止发送 1=使能发送 */
        __IOM uint32_t IDLEIE  :1;  /*!< IDLE中断使能 (IDLE interrupt enable) 0=禁止产生IDLE中断 1=允许产生IDLE中断 */
        __IOM uint32_t RXNEIE  :1;  /*!< 接收缓冲区非空中断使能 (RXNE interrupt enable) 0=禁止中断 1=使能中断 */
        __IOM uint32_t TCIE    :1;  /*!< 发送完成中断使能 (Transmission complete interrupt enable) 0=禁止中断 1=TC为1时产生中断 */
        __IOM uint32_t TXEIE   :1;  /*!< 发送缓冲区空中断使能 (TXE interrupt enable) 0=禁止中断 1=TXE为1时产生中断 */
        __IOM uint32_t PEIE    :1;  /*!< PE中断使能 (PE interrupt enable) 0=禁止中断 1=PE为1时产生中断 */
        __IOM uint32_t PS      :1;  /*!< 校验选择 (Parity selection) 0=偶校验 1=奇校验 */
        __IOM uint32_t PCE     :1;  /*!< 检验控制使能 (Parity control enable) 0=禁止校验 1=使能校验 */
        __IOM uint32_t WAKE    :1;  /*!< 唤醒的方法 (Wakeup method) 0=被空闲总线唤醒 1=被地址标记唤醒 */
        __IOM uint32_t M       :1;  /*!< 字长 (Word length) 0=1起始位/8数据位/n停止位 1=1起始位/9数据位/n停止位 */
        __IOM uint32_t UE      :1;  /*!< USART使能 (USART enable) */
              uint32_t RSV     :18;
    };
    __IOM uint32_t reg;
} UN_USART_CR1;

/** 
  * @brief  控制寄存器 2(USART_CR2)
  * @note   地址偏移： 0x10  复位值： 0x0000
  */
typedef union {
    struct {
        __IOM uint32_t ADD   :4;  /*!< 本设备的USART节点地址 */
              uint32_t RSV1  :1;
        __IOM uint32_t LBDL  :1;  /*!< LIN断开符检测长度 (LIN break detection length) */
        __IOM uint32_t LBDIE :1;  /*!< LIN断开符检测中断使能 (LIN break detection interrupt enable) */
              uint32_t RSV2  :1;
        __IOM uint32_t LBCL  :1;  /*!< 最后一位时钟脉冲 (Last bit clock pulse) */
        __IOM uint32_t CPHA  :1;  /*!< 时钟相位 (Clock phase) */
        __IOM uint32_t CPOL  :1;  /*!< 时钟极性 (Clock polarity) */
        __IOM uint32_t CLKEN :1;  /*!< CLKEN：时钟使能 (Clock enable) 0=禁止CK引脚 1=使能CK引脚 */
        __IOM uint32_t STOP  :2;  /*!< 停止位 (STOP bits) 00=1个停止位 01=0.5个停止位 10=2个停止位 11=1.5个停止位 */
        __IOM uint32_t LINEN :1;  /*!< LIN模式使能 (LIN mode enable) 0=禁止LIN模式 1=使能LIN模式 */
              uint32_t RSV3  :17;
    };
    __IOM uint32_t reg;
} UN_USART_CR2;

/** 
  * @brief  控制寄存器 3(USART_CR3)
  * @note   地址偏移： 0x14  复位值： 0x0000
  */
typedef union {
    struct {
        __IOM uint32_t EIE   :1;  /*!< 错误中断使能 (Error interrupt enable)，多缓冲区通信模式下使用 */
        __IOM uint32_t IREN  :1;  /*!< 红外模式使能 (IrDA mode enable) */
        __IOM uint32_t ERLP  :1;  /*!< 红外低功耗 (IrDA low-power) */
        __IOM uint32_t HDSEL :1;  /*!< 半双工选择 (Half-duplex selection) */
        __IOM uint32_t NACK  :1;  /*!< 智能卡NACK使能 (Smartcard NACK enable) */
        __IOM uint32_t SCEN  :1;  /*!< 智能卡模式使能 (Smartcard mode enable) */
        __IOM uint32_t DMAR  :1;  /*!< DMA使能接收 (DMA enable receiver) 0=禁止接收DMA 1=使能接收DMA */
        __IOM uint32_t DMAT  :1;  /*!< DMA使能发送 (DMA enable transmitter) 0=禁止发送DMA 1=使能发送DMA */
        __IOM uint32_t RTSE  :1;  /*!< RTS使能 (RTS enable) */
        __IOM uint32_t CTSE  :1;  /*!< CTS使能 (CTS enable) */
        __IOM uint32_t CTSIE :1;  /*!< CTS中断使能 (CTS interrupt enable) */
              uint32_t RSV   :21;
    };
    __IOM uint32_t reg;
} UN_USART_CR3;

/** 
  * @brief  保护时间和预分频寄存器(USART_GTPR)
  * @note   地址偏移： 0x18  复位值： 0x0000
  */
typedef union {
    struct {
        __IOM uint32_t PSC :8;  /*!< 预分频器值 (Prescaler value)，用于红外和智能卡模式 */
        __IOM uint32_t GT  :8;  /*!< 保护时间值 (Guard time value)，用于智能卡模式 */
              uint32_t RSV :16;
    };
    __IOM uint32_t reg;
} UN_USART_GTPR;

/** 
  * @brief Universal Synchronous Asynchronous Receiver Transmitter
  */
typedef struct
{
  __IM  UN_USART_SR   SR;    /*!< USART Status register,                   Address offset: 0x00 */
  __IOM UN_USART_DR   DR;    /*!< USART Data register,                     Address offset: 0x04 */
  __IOM UN_USART_BRR  BRR;   /*!< USART Baud rate register,                Address offset: 0x08 */
  __IOM UN_USART_CR1  CR1;   /*!< USART Control register 1,                Address offset: 0x0C */
  __IOM UN_USART_CR2  CR2;   /*!< USART Control register 2,                Address offset: 0x10 */
  __IOM UN_USART_CR3  CR3;   /*!< USART Control register 3,                Address offset: 0x14 */
  __IOM UN_USART_GTPR GTPR;  /*!< USART Guard time and prescaler register, Address offset: 0x18 */
} USART_TypeDef;

#define USART1   ((USART_TypeDef *)USART1_BASE)   /*!< USART1 寄存器定义 */
#define USART2   ((USART_TypeDef *)USART2_BASE)   /*!< USART2 寄存器定义 */
#define USART3   ((USART_TypeDef *)USART3_BASE)   /*!< USART3 寄存器定义 */

typedef enum {
    USART_IDX1 = 0,
    USART_IDX2,
    USART_IDX3,
    USART_IDX_BUTT
} EN_USART_IDX;

typedef enum {
    USART_BAUD_9600 = 9600,
    USART_BAUD_115200 = 115200
} EN_USART_BAUD;

typedef enum {
    USART_WORD_LENGTH_8 = 0,  /*!< 一个起始位， 8个数据位， n个停止位 */
    USART_WORD_LENGTH_9 = 1   /*!< 一个起始位， 9个数据位， n个停止位 */
} EN_USART_WORD_LENGTH;

typedef enum {
    USART_STOP_1  = 0,  /*!< 1个停止位 */
    USART_STOP_05 = 1,  /*!< 0.5个停止位 */
    USART_STOP_2  = 2,  /*!< 2个停止位 */
    USART_STOP_15 = 3   /*!< 1.5个停止位 */
} EN_USART_STOP;

typedef enum {
    USART_PARITY_EVEN = 0,  /*!< 偶校验 */
    USART_PARITY_ODD  = 1,  /*!< 奇校验 */
    USART_PARITY_NONE       /*!< 无校验 */
} EN_USART_PARITY;

typedef struct {
    EN_USART_IDX enUsart;     /*!< 串口号 */
    EN_USART_BAUD baudRate;   /*!< 波特率 */
    EN_USART_WORD_LENGTH wordLength;  /*!< 数据长度，即寄存器M位，8B还是9B */
    EN_USART_STOP stopBits;   /*!< 停止位长度 */
    EN_USART_PARITY parity;   /*!< 是否开启奇偶校验 */
    uint32_t isEnableIrq;     /*!< Enable=使能中断模式 DISABLE=关闭中断模式 */
    uint32_t isUseDma;        /*!< Enable=RX/TX使用DMA传输 DISABLE=不使用DMA */
} ST_USART_CTRL;

uint32_t USART_Init(ST_USART_CTRL *pstUsartInit);
void USART_SyncTransmit(EN_USART_IDX usart, char *pData); // 同步串口输出，不涉及BUF
void UART_BufInit(void);  // 异步输入输出时需要开启BUF

#endif